package com.yongbao.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.jwt.JWTUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yongbao.common.Constants;
import com.yongbao.common.PageInfo;
import com.yongbao.common.WebResponse;
import com.yongbao.common.config.ConfigurationConfig;
import com.yongbao.common.config.WechatConfigurationConfig;
import com.yongbao.common.enums.BooleanEnum;
import com.yongbao.common.service.RedisService;
import com.yongbao.common.utils.AssertUtil;
import com.yongbao.mapper.DishOrderMapper;
import com.yongbao.mapper.UserMapper;
import com.yongbao.model.customdo.WeChatSession;
import com.yongbao.model.domain.DishOrderDO;
import com.yongbao.model.domain.DishOrderSubDO;
import com.yongbao.model.domain.UserDO;
import com.yongbao.model.dtomapper.UserDtoMapper;
import com.yongbao.model.request.UserRequest;
import com.yongbao.model.request.manual.AuthLoginParam;
import com.yongbao.model.request.manual.UserUpdateRequest;
import com.yongbao.model.util.UserConvert;
import com.yongbao.model.vo.UserVO;
import com.yongbao.model.vo.manual.GetPhoneNumberVO;
import com.yongbao.service.DishOrderSubService;
import com.yongbao.service.UserService;
import com.yongbao.utils.WXUtils;
import com.vdurmont.emoji.EmojiParser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * @author zhanghong
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DishOrderSubService dishOrderSubService;
    @Autowired
    private DishOrderMapper dishOrderMapper;

    @Override
    public UserVO getByKey(long id) {
        UserDO userDO = getById(id);
        UserVO userVO = UserDtoMapper.INSTANCE.do2VO(userDO);
        return userVO;
    }

    @Override
    public PageInfo<UserVO> pageQuery(UserRequest request) {
        long count = userMapper.pageCount(request);
        List<UserDO> list = userMapper.pageQuery(request, request.getPageSize(), request.fetchOffSet());
        List<UserVO> userVOList = UserConvert.buildUserVoList(list);
        for (UserVO userVO : userVOList) {
            Long joinCount = dishOrderSubService.lambdaQuery().eq(DishOrderSubDO::getUserId, userVO.getId()).eq(DishOrderSubDO::getHeadGroup, 1).count();
            userVO.setJoinCount(joinCount);
            Long headGroupCount = dishOrderSubService.lambdaQuery().eq(DishOrderSubDO::getUserId, userVO.getId()).eq(DishOrderSubDO::getHeadGroup, 1).count();
            userVO.setHeadGroupCount(headGroupCount);
//            DishOrderDO dishOrderDO = dishOrderMapper.queryRecentJoinByUserId(userVO.getId());
//            if (dishOrderDO != null) {
//                userVO.setRecentJoinAddress(String.format("%s%s%s", dishOrderDO.getAreaName(), dishOrderDO.getStreetName(), dishOrderDO.getAddress()));
//            }
        }
        return new PageInfo(request.getPageNum(), request.getPageSize(), userVOList, count);
    }

    @Override
    public List<UserVO> listQuery(UserRequest request) {
        List<UserDO> list = list();
        List<UserVO> userVOS = UserConvert.buildUserVoList(list);
        return userVOS;
    }

    @Override
    public Boolean add(UserRequest request) {
        UserDO userDO = UserDtoMapper.INSTANCE.request2DO(request);
        save(userDO);
        return true;
    }

    @Override
    public Boolean updateByKey(UserUpdateRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        UserDO userDO = UserDtoMapper.INSTANCE.request2DO(request);
        userMapper.updateDO(userDO);
        return true;
    }

    @Override
    public Boolean deleteByIds(String ids) {
        userMapper.deleteDOByIds(Convert.toStrArray(ids));
        return true;
    }

    /**
     * 微信授权登录获取token
     * @param param
     * @return
     */
    @Override
    @Transactional
    public WebResponse<String> authLogin(AuthLoginParam param) {
        WebResponse<WeChatSession> response = WXUtils.getOpenId(param.getCode(), WechatConfigurationConfig.wxUserWechatAppid, WechatConfigurationConfig.wxUserWechatSecret);
        if (!StringUtils.equals(response.getStatus(), WebResponse.STATUS_SUCCESS)) {
            return new WebResponse<>(response.getCode(), response.getMessage());
        }
        WeChatSession weChatSession = response.getData();
        String openid = weChatSession.getOpenid();
        UserDO xcxUser = userMapper.queryByOpenid(openid);

        if (xcxUser == null) {
            xcxUser = new UserDO();
            xcxUser.setNickName(EmojiParser.parseToAliases(param.getNickName()));
            xcxUser.setAvatar(param.getAvatar());
            xcxUser.setMobile(param.getPhoneNumber());
            xcxUser.setOpenId(openid);
            userMapper.insertDO(xcxUser);
            xcxUser = userMapper.selectDOById(xcxUser.getId());
        } else {
            //校验是否已经被禁用
            //AssertUtil.assertTrue(xcxUser.getStatus() != null && xcxUser.getStatus() == BooleanEnum.TRUE.getCode(), ErrorCode.PARAM_ERROR, "账号禁用中，请联系平台");
        }

        // 生成token
        Map<String, Object> map = JSON.parseObject(JSON.toJSONString(xcxUser), Map.class);
        String token = JWTUtil.createToken(map, ConfigurationConfig.applicationName.getBytes());
        redisService.set(String.format(Constants.LOGIN_USER_RDB_PREFIX, token), JSON.toJSONString(xcxUser));
        return new WebResponse<>(token);
    }

    /**
     * 微信授权获取手机号
     * @param code
     * @return
     */
    @Override
    public WebResponse<GetPhoneNumberVO> getPhoneNumber(String code) {
        WebResponse<String> phoneResponse = WXUtils.getPhone(code, WechatConfigurationConfig.wxUserWechatAppid, WechatConfigurationConfig.wxUserWechatSecret);
        GetPhoneNumberVO getPhoneNumberVO = new GetPhoneNumberVO();
        getPhoneNumberVO.setRegister(BooleanEnum.FALSE.getCode());
        if (StringUtils.isNotBlank(phoneResponse.getData())) {
            getPhoneNumberVO.setPhoneNumber(phoneResponse.getData());
            UserDO xcxUser = userMapper.queryUserByMobile(phoneResponse.getData());
            if (xcxUser != null) {
                //校验是否已经被禁用
                //AssertUtil.assertTrue(xcxUser.getStatus() != null && xcxUser.getStatus() == BooleanEnum.TRUE.getCode(), ErrorCode.PARAM_ERROR, "账号禁用中，请联系平台");

                // 生成token
                Map<String, Object> map = JSON.parseObject(JSON.toJSONString(xcxUser), Map.class);
                String token = JWTUtil.createToken(map, ConfigurationConfig.applicationName.getBytes());
                token = DigestUtil.md5Hex(token);
                UserVO userVO = UserDtoMapper.INSTANCE.do2VO(xcxUser);
                redisService.set(String.format(Constants.LOGIN_USER_RDB_PREFIX, token), JSON.toJSONString(userVO));
                getPhoneNumberVO.setRegister(BooleanEnum.TRUE.getCode());
                getPhoneNumberVO.setToken(token);
            }
        }
        return new WebResponse<>(getPhoneNumberVO);
    }
}
